package com.wing.product.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.common.enums.MaintenanceEnum;
import com.wing.common.exception.BusinessException;
import com.wing.common.utils.UniqueIdGeneratorUtil;
import com.wing.device.model.entity.Device;
import com.wing.device.model.entity.DeviceModel;
import com.wing.device.model.entity.DeviceType;
import com.wing.device.service.DeviceModelService;
import com.wing.device.service.DeviceService;
import com.wing.device.service.DeviceTypeService;
import com.wing.dict.model.entity.DictLabel;
import com.wing.dict.service.DictLabelService;
import com.wing.enterprisecab.feign.EnterpriseCabClient;
import com.wing.enterprisecab.warehouse.WarehouseForm;
import com.wing.platform.order.model.entity.Warehouse;
import com.wing.product.dao.ProcessInfoDao;
import com.wing.product.model.entity.*;
import com.wing.product.model.request.ProcessInfoForm;
import com.wing.product.model.request.ProductTypeForm;
import com.wing.product.model.response.ProcessInfoVO;
import com.wing.res.model.entity.BenchmarkBook;
import com.wing.res.model.entity.ResBenchmarkBookBom;
import com.wing.res.model.entity.ResBenchmarkBookEchnology;
import com.wing.res.model.entity.ResBenchmarkBookEchnologySku;
import com.wing.res.model.response.DeviceOrWorkVo;
import com.wing.res.service.BenchmarkBookService;
import com.wing.res.service.ResBenchmarkBookBomService;
import com.wing.res.service.ResBenchmarkBookEchnologyService;
import com.wing.res.service.ResBenchmarkBookEchnologySkuService;
import com.wing.web.excel.ProcessInfoExcelIn;
import com.wing.web.excel.ProductDetailExcelIn;
import com.wing.web.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.pulsar.shade.org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * -ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class ProcessInfoServiceImpl extends ServiceImpl<ProcessInfoDao, ProcessInfo> implements ProcessInfoService {

    @Autowired
    ProductTypeService productTypeService;

    @Autowired
    EnterpriseCabClient enterpriseCabClient;

    @Autowired
    BenchmarkBookService benchmarkBookService;

    @Autowired
    ResBenchmarkBookBomService resBenchmarkBookBomService;

    @Autowired
    ResBenchmarkBookEchnologyService resBenchmarkBookEchnologyService;

    @Autowired
    ResBenchmarkBookEchnologySkuService resBenchmarkBookEchnologySkuService;

    @Autowired
    DeviceService deviceService;

    @Autowired
    DeviceTypeService deviceTypeService;


    @Autowired
    DeviceModelService deviceModelService;

    @Autowired
    private DictLabelService dictLabelService;

    @Autowired
    private ProductDetailService productDetailService;

    @Autowired
    private ProcessDeviceService processDeviceService;

    @Override
    public int add(ProcessInfoForm processInfoForm) {
        //校验
        ProcessInfo processInfo = new ProcessInfo();
        CopyOptions copyOptions = CopyOptions.create()
                .setEditable(ProcessInfo.class)
                .setIgnoreError(true)
                .setIgnoreNullValue(true);
        BeanUtil.copyProperties(processInfoForm, processInfo, copyOptions);
        //生成物资类别
        if ("0".equals(processInfo.getProductTypeIf())) {
            ProductType productType = new ProductType();
            productType.setCode(processInfo.getNodeCodes());
            productType.setName(processInfo.getNodeNames());
            productType.setMaterialNature(Integer.valueOf(processInfo.getProductTypeNature()));
            productType.setParentId(processInfo.getParentProductType());
            productType.setTypeServiceDepartment(processInfo.getTypeServiceDepartment());
            productType.setFinalClassifyStatus(1);
            productTypeService.save(productType);
            processInfo.setProductTypeId(productType.getId());
        }
        //创建工序仓
        if ("0".equals(processInfo.getProcessWarehouseIf())) {
            WarehouseForm warehouse = new WarehouseForm();
            warehouse.setWarehouseTypeId(2L);//默认:工序仓
            warehouse.setWarehouseFeatureType("1");//默认:自建
            warehouse.setWarehouseAttr("1");//默认:普通平仓
            warehouse.setCode(processInfo.getNodeCodes());
            warehouse.setName(processInfo.getNodeNames());
            warehouse.setWarehouseInoutNature("1");//默认:标准出入库流程
            warehouse.setStatus("0");
            enterpriseCabClient.warehouseAdd(warehouse);
            processInfo.setWarehouseId(warehouse.getId());
        }
        return baseMapper.insert(processInfo);
    }

    @Override
    public List<ProcessInfoVO> list4app(Map<String, Object> params) {
        return baseMapper.list4app(params);
    }

    @Override
    public Page<ProcessInfoVO> pageList4app(Page page, Map<String, Object> params) {
        List<ProcessInfoVO> list = baseMapper.list4app(page, params);
        page.setRecords(list);
        return page;
    }


    /**
     * 导入excel
     *
     * @param id
     * @param databaseUser
     * @return
     */
    @Override
    public ProcessInfoVO get4appById(Long id, String databaseUser) {
        return baseMapper.get4appById(id, databaseUser);
    }

    /**
     * 导入excel
     *
     * @param list
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importExcel(List<ProcessInfoExcelIn> list) {

        //"工序编码（产品编码+工序号）(*)", "物料编码(*)", "工序号(排序号)（*）", "工序名称(*)", "工序设备(*)",
        // "夹具编号(*)", "量具(*)", "工时定额(*)","工序类型","工序性质","是否支持委外",
        // "是否需要质检","检测频率"

        //查询物料code
        Set<String> collected = list.stream().map(ProcessInfoExcelIn::getSkuCode).collect(Collectors.toSet());


        List<DictLabel> dictLabelList = dictLabelService.list(null);

        Map<String, String> rateMap = dictLabelList.stream().filter(t -> "process_quality_rate".equals(t.getDictType())).collect(Collectors
                .toMap(DictLabel::getLabelName, DictLabel::getLabelValue));
        Map<String, String> natureMap = dictLabelList.stream().filter(t -> "process_nature".equals(t.getDictType())).collect(Collectors.toMap(
                DictLabel::getLabelName, DictLabel::getLabelValue
        ));
        Map<String, String> nodeMap = dictLabelList.stream().filter(t -> "process_node_type".equals(t.getDictType())).collect(Collectors.toMap(
                DictLabel::getLabelName, DictLabel::getLabelValue
        ));

        QueryWrapper<ProductDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted", 0);
        queryWrapper.in("sku_code", collected);
        List<ProductDetail> productDetails = productDetailService.list(queryWrapper);


        List<DeviceOrWorkVo> fessionlist = deviceModelService.fessionlist();
        List<DeviceOrWorkVo> devicelist = deviceModelService.devicelist();

        //物料map
        Map<String, ProductDetail> detailMap = productDetails.stream().collect(Collectors.toMap(ProductDetail::getSkuCode, detail -> detail));

        //将所有数据 根据skuCode 分组
        //有多少个产品 就有多少个基准书
        Map<String, List<ProcessInfoExcelIn>> processInfoExcelMap = list.stream()
                .collect(Collectors.groupingBy(ProcessInfoExcelIn::getSkuCode));
        //基准书相关
        if (CollectionUtil.isNotEmpty(processInfoExcelMap)) {
            for (Map.Entry<String, List<ProcessInfoExcelIn>> entry : processInfoExcelMap.entrySet()) {
                //生成基准书
                String key = entry.getKey();
                List<ProcessInfoExcelIn> value = entry.getValue();
                //res_benchmark_book
                BenchmarkBook benchmarkBook = new BenchmarkBook();
                //工序导入
                benchmarkBook.setResTaskId(100001L);
                benchmarkBook.setSkuCode(key);
                //（打样）基准书
                benchmarkBook.setBookType("1");
                ProductDetail productDetail = detailMap.get(key);
                if (ObjectUtil.isNotNull(productDetail)) {
                    benchmarkBook.setSkuName(productDetail.getSkuName());
                    benchmarkBook.setProductDetailId(productDetail.getId());
                    benchmarkBook.setSkuSpec(productDetail.getSkuSpec());

                    benchmarkBook.setProductType(productDetail.getProductTypeId());
                    benchmarkBook.setMaterialNature(productDetail.getMaterialNature());
                    benchmarkBook.setProductAttr(productDetail.getAssemblyNature());
                }
                //导入
                String JZS = UniqueIdGeneratorUtil.generateUniqueId("BK", "yyyyMMdd", 1000, 9999);
                benchmarkBook.setSource("3");
                benchmarkBook.setMakePerson(JwtUtils.getLoginUserId());
                benchmarkBook.setCreateTime(LocalDateTime.now());
                benchmarkBook.setStatus(MaintenanceEnum.BenchmarkBookStatus.DCS.getCode());
                benchmarkBook.setIsRelevance("0");
                benchmarkBook.setCode(JZS);
                boolean save = this.benchmarkBookService.save(benchmarkBook);
                //保存
                if (save) {
                    //生成默认的BOM规划根节点
                    ResBenchmarkBookBom resBenchmarkBookBom = new ResBenchmarkBookBom();
                    resBenchmarkBookBom.setCreatorName(JwtUtils.getLoginUsername());
                    resBenchmarkBookBom.setCreateTime(LocalDateTime.now());
                    resBenchmarkBookBom.setCreator(JwtUtils.getLoginUserId());
                    resBenchmarkBookBom.setProductDetailId(productDetail.getId());
                    resBenchmarkBookBom.setSkuCode(productDetail.getSkuCode());
                    //设置为根节点
                    resBenchmarkBookBom.setParentId(-1L);
                    resBenchmarkBookBom.setCount(BigDecimal.ONE);
                    resBenchmarkBookBom.setIsFinal(false);
                    resBenchmarkBookBom.setIsDeleted(false);
                    resBenchmarkBookBom.setHasChild(true);
                    resBenchmarkBookBom.setHasEnableChild(false);
                    resBenchmarkBookBom.setBookId(benchmarkBook.getId());
                    this.resBenchmarkBookBomService.save(resBenchmarkBookBom);
                    //生成工序
                    for (ProcessInfoExcelIn processInfoExcelIn : value) {
                        ResBenchmarkBookEchnology resBenchmarkBookEchnology = new ResBenchmarkBookEchnology();
                        resBenchmarkBookEchnology.setCreatorName(JwtUtils.getLoginUsername());
                        resBenchmarkBookEchnology.setCreator(JwtUtils.getLoginUserId());
                        resBenchmarkBookEchnology.setCreateTime(LocalDateTime.now());
                        resBenchmarkBookEchnology.setSkuCode(processInfoExcelIn.getSkuCode());
                        resBenchmarkBookEchnology.setCode(processInfoExcelIn.getCode());
                        resBenchmarkBookEchnology.setBookId(benchmarkBook.getId());
                        resBenchmarkBookEchnology.setName(processInfoExcelIn.getNodeNames());
                        resBenchmarkBookEchnology.setSorted(Integer.valueOf(processInfoExcelIn.getSortNumber()));
                        resBenchmarkBookEchnology.setContent(processInfoExcelIn.getContent());
                        resBenchmarkBookEchnology.setSalaryQuota(processInfoExcelIn.getSalaryQuota());
                        resBenchmarkBookEchnology.setNgSalaryQuota(processInfoExcelIn.getNgSalaryQuota());
                        if (ObjectUtil.isNotEmpty(rateMap)) {
                            resBenchmarkBookEchnology.setQualityType(rateMap.get(processInfoExcelIn.getQualityRate()));
                        }
                        resBenchmarkBookEchnology.setDeviceType(processInfoExcelIn.getDeviceType());

                        //设备
                        if (ObjectUtil.isNotEmpty(processInfoExcelIn.getWorkstationNature())
                                && MaintenanceEnum.workstationEmum.SBGW.getName()
                                .equals(processInfoExcelIn.getWorkstationNature())) {
                            resBenchmarkBookEchnology.setWorkstationNature(MaintenanceEnum.workstationEmum.SBGW.getCode());
                            for (DeviceOrWorkVo vo : devicelist) {
                                if (vo.getDeviceName().equals(processInfoExcelIn.getDeviceType())){
                                    resBenchmarkBookEchnology.setDeviceType(vo.getId().toString());
                                }
                            }

                        }
                        //人工
                        else if(ObjectUtil.isNotEmpty(processInfoExcelIn.getWorkstationNature())
                                && MaintenanceEnum.workstationEmum.RGGW.getName()
                                .equals(processInfoExcelIn.getWorkstationNature())){
                            resBenchmarkBookEchnology.setWorkstationNature(MaintenanceEnum.workstationEmum.RGGW.getCode());
                            for (DeviceOrWorkVo fe : fessionlist) {
                                if (fe.getDeviceName().equals(processInfoExcelIn.getWorkOrMachine())){
                                    resBenchmarkBookEchnology.setDeviceType(fe.getId().toString());
                                }
                            }
                        }

                        //人员工种
                        if(ObjectUtil.isNotEmpty(processInfoExcelIn.getPersonnelWorkType())){
                            for (DeviceOrWorkVo fe : fessionlist) {
                                if (fe.getDeviceName().equals(processInfoExcelIn.getWorkOrMachine())){
                                    resBenchmarkBookEchnology.setPersonnelWorkType(fe.getId());
                                }
                            }
                        }
                        resBenchmarkBookEchnology.setUnitId(processInfoExcelIn.getUnitId());
                        resBenchmarkBookEchnology.setFixture(processInfoExcelIn.getFixture());
                        resBenchmarkBookEchnology.setMeasuringTools(processInfoExcelIn.getMeasuringTools());
                        resBenchmarkBookEchnology.setHoursQuota(processInfoExcelIn.getHoursQuota()==null?BigDecimal.ZERO:processInfoExcelIn.getHoursQuota());
                        this.resBenchmarkBookEchnologyService.save(resBenchmarkBookEchnology);
//                        boolean save1 = this.resBenchmarkBookEchnologyService.save(resBenchmarkBookEchnology);
//                        if (save1) {
//                            ResBenchmarkBookEchnologySku resBenchmarkBookEchnologySku = new ResBenchmarkBookEchnologySku();
//                            resBenchmarkBookEchnologySku.setEchnologyId(resBenchmarkBookEchnology.getId());
//                            resBenchmarkBookEchnologySku.setProductDetailId(productDetail.getId());
//                            resBenchmarkBookEchnologySku.setCreateTime(LocalDateTime.now());
//                            resBenchmarkBookEchnologySku.setCreator(JwtUtils.getLoginUserId());
//                            resBenchmarkBookEchnologySku.setCreateTime(LocalDateTime.now());
//                            resBenchmarkBookEchnologySku.setSkuName(processInfoExcelIn.getSkuCode());
//                            resBenchmarkBookEchnologySku.setRemark("导入默认生成！");
//                            resBenchmarkBookEchnologySku.setQuantity(1);
//                            this.resBenchmarkBookEchnologySkuService.save(resBenchmarkBookEchnologySku);
//                        }
                    }

                }
            }
        }

        for (ProcessInfoExcelIn process : list) {
            //查询是否已有工序
            QueryWrapper<ProcessInfo> queryWrap = new QueryWrapper<>();
            queryWrap.eq("node_codes", process.getCode());
            ProcessInfo one = this.getOne(queryWrap);
            if (ObjectUtil.isNull(one)) {
                //工序信息插入
                ProcessInfo processInfo = new ProcessInfo();
                processInfo.setCreator(JwtUtils.getLoginUserId());
                processInfo.setCreateTime(LocalDateTime.now());
                processInfo.setCreatorName(JwtUtils.getLoginUsername());
                processInfo.setNodeNames(process.getNodeNames());
                processInfo.setNodeCodes(process.getCode());
                processInfo.setSortNumber(Integer.valueOf(process.getSortNumber()));
                processInfo.setSalaryQuota(process.getSalaryQuota());
                processInfo.setHoursQuota(process.getHoursQuota()==null?BigDecimal.ZERO:process.getHoursQuota());
                processInfo.setFixture(process.getFixture());

                //人工工种
                if(ObjectUtil.isNotEmpty(process.getPersonnelWorkType())){
                    for (DeviceOrWorkVo fe : fessionlist) {
                        if (fe.getDeviceName().equals(process.getWorkOrMachine())){
                            processInfo.setPersonnelWorkType(fe.getId());
                        }
                    }
                }
                processInfo.setMeasuringTools(process.getMeasuringTools());
                processInfo.setNgSalaryQuota(process.getNgSalaryQuota());
                processInfo.setUnitId(process.getUnitId());
                processInfo.setBfSalaryQuota(process.getBfSalaryQuota()==null?BigDecimal.ZERO:process.getBfSalaryQuota());
                processInfo.setStatus("1");

                //设备
                if (ObjectUtil.isNotEmpty(process.getWorkstationNature())
                        && MaintenanceEnum.workstationEmum.SBGW.getName()
                        .equals(process.getWorkstationNature())) {
                    processInfo.setWorkstationNature(MaintenanceEnum.workstationEmum.SBGW.getCode());
                    for (DeviceOrWorkVo vo : devicelist) {
                        if (vo.getDeviceName().equals(process.getDeviceType())){
                            processInfo.setDeviceType(vo.getId());
                        }
                    }

                }
                //人工
                else if(ObjectUtil.isNotEmpty(process.getWorkstationNature())
                        && MaintenanceEnum.workstationEmum.RGGW.getName()
                        .equals(process.getWorkstationNature())){
                    processInfo.setWorkstationNature(MaintenanceEnum.workstationEmum.RGGW.getCode());
                    for (DeviceOrWorkVo fe : fessionlist) {
                        if (fe.getDeviceName().equals(process.getWorkOrMachine())){
                            processInfo.setDeviceType(fe.getId());
                        }
                    }
                }
                //工序性质
                if (ObjectUtil.isNotEmpty(natureMap)) {
                    processInfo.setProcessNature(natureMap.get(process.getProcessNatureName()));
                }
                //物料类别性质
                if (ObjectUtil.isNotEmpty(nodeMap)) {
                    String nodeMapStr = nodeMap.get(process.getNodeTypesName());
                    if (StrUtil.isNotEmpty(nodeMapStr)) {
                        processInfo.setNodeTypes(Long.valueOf(nodeMapStr));
                    }
                }
                //1
                if ("是".equals(process.getIsOutsource())) {
                    processInfo.setIsOutsource("1");
                } else {
                    processInfo.setIsOutsource("2");
                }
                //1
                if ("是".equals(process.getQualityIf())) {
                    processInfo.setQualityIf("1");
                } else {
                    processInfo.setQualityIf("2");
                }
                //1
                if (ObjectUtil.isNotEmpty(rateMap)) {
                    processInfo.setQualityRate(rateMap.get(process.getQualityRate()));
                }
                processInfo.setInoutStatus("0");
                processInfo.setGuaranteeStatus("0");
                processInfo.setThingCodeStatus("0");
                processInfo.setProcessWarehouseIf("0");
                this.save(processInfo);
            }
        }
    }
}
